package com.daka.tools.poi;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExcelReader implements FileReader {
    private File file;
    private InputStream inStream = null;
    private Sheet sheet;
    private int currentRow;
    private int fromCol = 0;
    private int toCol = 99999;
    private String errMsg;

    public ExcelReader(File file) {
        this.setFileName(file);
    }

    public boolean BeginRead() {
        try {
            Workbook workbook;
            FileInputStream in = new FileInputStream(file);//get file
            if (file.getName().toLowerCase().endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(in);//xlsx
            } else {
                workbook = new HSSFWorkbook(in);
            }
            sheet = workbook.getSheetAt(0);//read index 0

            if (sheet == null) {
                return true;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void EndRead() {
        if (this.inStream != null) {
            try {
                this.inStream.close();
            } catch (IOException e) {
                errMsg = e.getMessage();
            }
        }

    }

    private String[] ReadLine(int row) {
        Row rw = this.sheet.getRow(row);
        if (rw == null) {
            return null;
        }

        int fc = this.fromCol;
        int tc = this.toCol;

        String[] strs = new String[tc - fc + 1];

        for (int i = fc; i <= tc; i++) {
            strs[i - fc] = this.getCellStringValue(rw.getCell(i));
        }
        return strs;
    }

    private String getCellStringValue(Cell cell) {
        String result = null;
        if (cell != null) {
            if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
                result = cell.getStringCellValue();
            } else if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    double d = cell.getNumericCellValue();
                    Date date = HSSFDateUtil.getJavaDate(d);
                    result = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(date);
                } else {
                    result = cell.getNumericCellValue() + "";
                    if (".".equals(result.charAt(result.length() - 1) + "")) {
                        result = result.substring(0, result.length() - 1);
                    }
                }
            } else if (Cell.CELL_TYPE_FORMULA == cell.getCellType()) {
                result = cell.getStringCellValue();
            }
        }

        return result;
    }

    public void initRange() throws Exception {
        this.fromCol = -1;
        this.toCol = -1;
        Row rw = this.sheet.getRow(this.sheet.getFirstRowNum());
        if (rw == null) {
            throw new Exception("sheet read error");
        }

        int fc = rw.getFirstCellNum();
        int tc = rw.getLastCellNum();

        String[] strs = new String[tc - fc + 1];

        for (int i = fc; i <= tc; i++) {
            strs[i - fc] = this.getCellStringValue(rw.getCell(i));
        }

        this.fromCol = fc;
        this.toCol = tc;

        int c = 0;
        while (strs[c] == null || "".equals(strs[0])) {
            this.fromCol = this.fromCol + 1;
            c++;
            if (c > strs.length - 1) break;
        }

        c = tc;
        while (strs[c] == null || "".equals(strs[0])) {
            this.toCol = this.toCol - 1;
            c--;
            if (c < 0) break;
        }
    }

    public String[] ReadHeader() {
        return this.ReadLine(this.sheet.getFirstRowNum());
    }

    public boolean hasNext() {
        return this.currentRow < this.sheet.getLastRowNum();
    }

    public String[] ReadNext() {
        this.currentRow = this.currentRow + 1;

        return this.ReadLine(this.currentRow);
    }

    public int getCount() {
        return this.sheet.getLastRowNum() - this.sheet.getFirstRowNum();
    }

    public String getErrorMsg() {
        return errMsg;
    }

    @SuppressWarnings("unused")
    private static String array2Str(String[] data) {
        String s = "";
        for (String ss : data) {
            s = s + "," + ss;
        }
        return s.substring(1);
    }

    public void setFileName(File file) {
        this.file = file;
    }

    @SuppressWarnings("unused")
    public File getFileName() {
        return file;
    }

}
